{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 逻辑回归\n",
    "\n",
    "逻辑回归的优点有：可以用现有的数值优化算法求解\n",
    "\n",
    "# 梯度下降\n",
    "\n",
    "梯度：梯度的本意是一个向量，由函数对每个参数的偏导组成，表示某一函数在该点处的方向导数沿着该方向取得最大值，即函数在该点处沿着该方向变化最快，变化率最大。\n",
    "\n",
    "在传统机器学习中，损失函数通常为凸函数，假设此时只有一个参数，则损失函数对参数的梯度即损失函数对参数的导数。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# -*- coding: utf-8 -*-\n",
    "\n",
    "import numpy as np\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "def gradient_descent(initial_theta,eta=0.05,n_iters=1000,epslion=1e-8):\n",
    "    '''\n",
    "    梯度下降\n",
    "    :param initial_theta: 参数初始值，类型为float\n",
    "    :param eta: 学习率，类型为float\n",
    "    :param n_iters: 训练轮数，类型为int\n",
    "    :param epslion: 容忍误差范围，类型为float\n",
    "    :return: 训练后得到的参数\n",
    "    '''\n",
    "    #   请在此添加实现代码   #\n",
    "    #********** Begin *********#\n",
    "    for i in range(0, n_iters):\n",
    "        initial_theta -= eta * 2*(initial_theta - 3)\n",
    "        if (initial_theta < epslion):\n",
    "            break\n",
    "\n",
    "    return initial_theta\n",
    "    #********** End **********#\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 动手实现逻辑回归 - 癌细胞精准识别\n",
    "\n",
    "[网页链接](https://www.educoder.net/tasks/u8xhtqklro4w)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# -*- coding: utf-8 -*-\n",
    "\n",
    "import numpy as np\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "\n",
    "def sigmoid(x):\n",
    "    '''\n",
    "    sigmoid函数\n",
    "    :param x: 转换前的输入\n",
    "    :return: 转换后的概率\n",
    "    '''\n",
    "    return 1/(1+np.exp(-x))\n",
    "\n",
    "\n",
    "def fit(x,y,eta=1e-3,n_iters=10000):\n",
    "    '''\n",
    "    训练逻辑回归模型\n",
    "    :param x: 训练集特征数据，类型为ndarray，x的行数为样本数量，列数为特征数量\n",
    "    :param y: 训练集标签，类型为ndarray\n",
    "    :param eta: 学习率，类型为float\n",
    "    :param n_iters: 训练轮数，类型为int\n",
    "    :return: 模型参数，类型为ndarray\n",
    "    '''\n",
    "    #   请在此添加实现代码   #\n",
    "    #********** Begin *********#\n",
    "    theta = np.zeros(x.shape[1])\n",
    "    for i in range(0, n_iters):\n",
    "        z = np.dot(x, theta)\n",
    "        a = sigmoid(z)\n",
    "        theta -= eta * np.dot(x.T, a-y.reshape(a.shape))\n",
    "    #********** End **********#\n",
    "    return theta\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 手写数字识别\n",
    "\n",
    "`LogisticRegression`\n",
    "`LogisticRegression`中默认实现了 OVR ，因此``LogisticRegression``可以实现多分类。`LogisticRegression`的构造函数中有三个常用的参数可以设置：\n",
    "\n",
    "- `solver` ：`{'newton-cg' ,  'lbfgs',  'liblinear',  'sag',  'saga'}`， 分别为几种优化算法。默认为`liblinear`；\n",
    "- C：正则化系数的倒数，默认为 1.0 ，越小代表正则化越强；\n",
    "- max_iter：最大训练轮数，默认为 100 。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.linear_model import LogisticRegression\n",
    "import warnings\n",
    "warnings.filterwarnings(\"ignore\")\n",
    "def digit_predict(train_image, train_label, test_image):\n",
    "    '''\n",
    "    实现功能：训练模型并输出预测结果\n",
    "    :param train_sample: 包含多条训练样本的样本集，类型为ndarray,shape为[-1, 8, 8]\n",
    "    :param train_label: 包含多条训练样本标签的标签集，类型为ndarray\n",
    "    :param test_sample: 包含多条测试样本的测试集，类型为ndarry,shape为[-1, 8, 8]\n",
    "    :return: test_sample对应的预测标签\n",
    "    '''\n",
    "\n",
    "    #************* Begin ************#\n",
    "    X_train = train_image.reshape(-1, 64)\n",
    "    y_train = train_label.reshape(-1, 1)\n",
    "    X_test = test_image.reshape(-1, 64)\n",
    "    lr = LogisticRegression(max_iter = 110, solver='saga')\n",
    "    lr.fit(X_train, y_train)\n",
    "    y_pred = lr.predict(X_test)\n",
    "    return y_pred\n",
    "    #************* End **************#"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "tf38",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.19"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
